#ifndef _COUNTER_H_
#define _COUNTER_H_
#include <stdio.h>
#include <iostream>
using namespace std;

template <typename T>
class SmartPtr;

template <typename T>
class Counter
{
private:
    T *ptr;  //对象指针
    int cnt; //引用计数器

    friend class SmartPtr<T>;

    Counter(T *p)
    {
        ptr = p;
        cnt = 1;
    }

    ~Counter()
    {
        delete ptr;
    }
};

#include <iostream>
template <typename T>
class SmartPtr
{
private:
    Counter<T> *ptr_cnt;
    int num = 0;
    static int index;

public:
    SmartPtr(void)
    {
        ptr_cnt = NULL;
        num = index++;
        cout << "SmartPtr(void)" << endl;
    }
    //  成员函数
    //  普通构造函数  初始化计数类
    SmartPtr(T *p)
    {
        ptr_cnt = new Counter<T>(p);
        num = index++;
        cout << "SmartPtr(T *p)" << endl;
    }
    //  拷贝构造函数
    SmartPtr(const SmartPtr &other)
    {
        ptr_cnt = other.ptr_cnt;
        ptr_cnt->cnt++;
        num = index++;
        cout << "SmartPtr(const SmartPtr &other)" << endl;
    }
    //  赋值运算符重载函数
    SmartPtr &operator=(SmartPtr &rhs)
    {
        reset();
        ptr_cnt = rhs.ptr_cnt;
        rhs.ptr_cnt->cnt++;
        cout << "operator" << endl;
        return *this;
    }
    //  解引用运算符重载函数
    T &operator*()
    {
        return *(ptr_cnt->cnt);
    }

    ~SmartPtr()
    {
        reset();
    }

    T *get() const
    {
        return *this;
    }

    int count() const
    {
        if (NULL == ptr_cnt)
            return -1;
        return ptr_cnt->cnt;
    }

    void reset(void)
    {
        if (ptr_cnt)
        {
            ptr_cnt->cnt--;
            if (count() == 0)
            {
                cout << "还有" << count() << "个指针指向基础对象" << endl;
                cout << "当前释放的是 : " << num << endl;
                cout << "已经释放了" << endl;
                delete ptr_cnt;
            }
            else
            {
                cout << "还有" << count() << "个指针指向基础对象" << endl;
                cout << "当前释放的是 : " << num << endl;
            }
        }
    }
};

template <typename T>
int SmartPtr<T>::index = 1;
#endif